<?php
// +----------------------------------------------------------------------
// | sfadmin - Suifeng Administration
// +----------------------------------------------------------------------
// | Copyright (c) 2017-2020 http://suifeng.tech All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: suifeng <1787585212@qq.com>
// +----------------------------------------------------------------------

namespace app\admin\common\utils;

use app\admin\common\utils\HtmlUtil;

class AdminForm
{
    public $array = array();
    public $errors = array();

    public function __construct($array, $errors)
    {
        $this->array = $array;
        $this->errors = $errors;
    }

    public function renderForm($options)
    {
        $submit_url = isset($options['submit_url']) ? $options['submit_url'] : null;
        $cancel_url = isset($options['cancel_url']) ? $options['cancel_url'] : null;
        $controls = isset($options['controls']) ? $options['controls'] : array();

        unset($options['submit_url'], $options['cancel_url'], $options['controls']);

//         $attributes['class'] = 'form';
//         $attributes['method'] = 'post';
//         $attributes['action'] = $submit_url;
        $html = '';//HtmlUtil::render_start_tag('form', $attributes);

        foreach ($controls as $field => $config) {
            if (isset($config['control'])) {
                $control = $config['control'];
                unset($config['control']);
            } else {
                $control = 'text';
            }

            if (isset($config['label'])) {
                $label = $config['label'];
                unset($config['label']);
            } else {
                $label = strtoupper($field);
            }

            if (isset($config['help'])) {
                $help = $config['help'];
                unset($config['help']);
            } else {
                $help = null;
            }

            $html .= $this->renderGroup($field, $label, $help, $control, $config);
        }

        $html .= HtmlUtil::renderTag('div', array('class' => 'form-group form-actions'), $this->renderSubmitAndCancel($submit_url, $cancel_url));
//         $html .= HtmlUtil::render_end_tag('form');

        return $html;
    }

    public function renderGroup($field, $label, $help, $control, $options = array())
    {
        $control_html = $this->renderControl($field, $label, $help, $control, $options);

        $attributes['class'] = 'form-group' . ($this->hasError($field) ? ' has-error' : '');
        return HtmlUtil::renderTag('div', $attributes, $control_html);
    }

    public function renderControl($field, $label, $help, $control, $options = array())
    {
        $label_html = $this->renderLabel($label, array('for' => $field));
        $help_html = $help ? $this->renderHelp($help) : null;
        $error_html = $this->hasError($field) ? $this->renderError($this->errors[$field]) : null;

        $control_method = 'render' . ucfirst($control);
        $control_html = $this->$control_method($field, $options);

        return $label_html . $control_html . $help_html . $error_html;
    }

    private function _renderInput($type, $name, $value, $attributes = array())
    {
        $attributes['type'] = $type;
        $attributes['name'] = $name;
        $attributes['value'] = $value;
        return HtmlUtil::renderTag('input', $attributes);
    }

    public function renderHidden($field, $options = array())
    {
        return $this->_renderInput('hidden', $field, $this->getValue($field), $options);
    }

    public function renderText($field, $options = array())
    {
        $attributes['class'] = 'form-control';
        $attributes = array_merge($attributes, $options);
        return $this->_renderInput('text', $field, $this->getValue($field), $attributes);
    }

    public function renderPassword($field, $options = array())
    {
        $attributes['class'] = 'form-control';
        $attributes = array_merge($attributes, $options);
        return $this->_renderInput('password', $field, $this->getValue($field), $attributes);
    }

    public function renderUrl($field, $options = array())
    {
        $attributes['class'] = 'form-control';
        $attributes = array_merge($attributes, $options);
        return $this->_renderInput('url', $field, $this->getValue($field), $attributes);
    }

    public function renderEmail($field, $options = array())
    {
        $attributes['class'] = 'form-control';
        $attributes = array_merge($attributes, $options);
        return $this->_renderInput('email', $field, $this->getValue($field), $attributes);
    }

    public function renderDecimal($field, $options = array())
    {
        $attributes['class'] = 'form-control format format-decimal';
        $attributes = array_merge($attributes, $options);
        return $this->_renderInput('text', $field, $this->getValue($field), $attributes);
    }

    public function renderNumber($field, $options = array())
    {
        $attributes['class'] = 'form-control format format-number';
        $attributes = array_merge($attributes, $options);
        return $this->_renderInput('text', $field, $this->getValue($field), $attributes);
    }

    public function renderDate($field, $options = array())
    {
        $attributes['class'] = 'form-control';
        $attributes['control'] = 'datetime-picker';
        $attributes['data-format'] = config('SYS_DATE_FORMAT');
        $attributes['value'] = $this->getValue($field);
        $attributes = array_merge($attributes, $options);
        return $this->_renderInput('text', $field, $this->formatValue($field, $options), $attributes);
    }

    public function renderTsdate($field, $options = array())
    {
        $attributes['class'] = 'form-control';
        $attributes['control'] = 'datetime-picker';
        $attributes['ref-hidden'] = $field;
        $attributes['data-format'] = config('SYS_DATE_FORMAT');
        $attributes['value'] = sf_format_date($this->getValue($field));
        $attributes = array_merge($attributes, $options);
        $input_html = HtmlUtil::renderTag('input', $attributes);
        $hidden_html = $this->renderHidden($field);
        return $input_html . $hidden_html;
    }

    public function renderColor($field, $options = array())
    {
        $attributes['class'] = 'form-control';
        $attributes = array_merge($attributes, $options);
        return $this->_renderInput('color', $field, $this->getValue($field), $attributes);
    }

    public function renderSwitch($field, $options = array())
    {
        $attributes['type'] = 'checkbox';
        $attributes['switch-ref'] = $field;
        if ($this->getValue($field)) {
            $attributes['checked'] = 'checked';
        }
        $attributes = array_merge($attributes, $options);
        $input_html = HtmlUtil::renderTag('input', $attributes);
        $hidden_html = $this->renderHidden($field);
        return HtmlUtil::renderTag('div', array('class' => 'sf-switch'), $input_html) . $hidden_html;
    }

    public function renderImage($field, $options = array())
    {
        //$options['data-preview-file-type'] = 'image';
//         $options['data-allowed-file-types'] = 'image';
//         $options['data-allowed-file-extensions'] = 'gif';
        return $this->renderFile($field, $options);
    }

    public function renderFile($field, $options = array())
    {
        $attributes['type'] = 'file';
        $attributes['control'] = 'bootstrap-fileinput';
        $attributes['ref-hidden'] = $field;
        $attributes['data-max-file-count'] = 1;
        list($file_ids, $file_list) = $this->_getFileList($this->getValue($field));
        $attributes['initial-file-list'] = $file_list;
        $attributes = array_merge($attributes, $options);
        $input_html = HtmlUtil::renderTag('input', $attributes);
        $hidden_html = $this->renderHidden($field, array('value' => $file_ids));
        return $input_html . $hidden_html;
    }

    private function _getFileList($value)
    {
        $file_list = array();
        $file_ids = array();
        foreach (explode(',', $value) as $file_id) {
            $file_info = model('admin/upload')->getFileInfo($file_id);
            if ($file_info) {
                $file_ids[] = $file_info['id'];
                $file_list[] = implode(',', array($file_info['id'], $file_info['name'], $file_info['size'], $file_info['url']));
            }
        }
        return array(implode(',', $file_ids), implode(';', $file_list));
    }

    public function renderHtml($field, $options = array())
    {
        $attributes['control'] = 'summernote';
        $attributes['ref-hidden'] = $field;
        $attributes['data-height'] = '300';
        $attributes = array_merge($attributes, $options);
        $div_html = HtmlUtil::renderTag('div', $attributes, $this->getValue($field));
        $hidden_html = $this->renderHidden($field);
        return $div_html . $hidden_html;
    }

    public function renderTextarea($field, $options = array())
    {
        $attributes['name'] = $field;
        $attributes['class'] = 'form-control';
        $attributes['rows'] = 10;
        $attributes = array_merge($attributes, $options);
        return HtmlUtil::renderTag('textarea', $attributes, $this->getValue($field));
    }

    public function getValue($field)
    {
        if (isset($this->array[$field])) {
            return $this->array[$field];
        } else {
            return null;
        }
    }

    public function formatValue($field, $options)
    {
        $value = $this->getValue($field);
        $format = isset($options['format']) ? $options['format'] : '';
        foreach (explode(',', $format) as $fun) {
            if (function_exists($fun)) {
                $value = $fun($value);
            }
        }
        return $value;
    }

    public function hasError($field)
    {
        return isset($this->errors[$field]);
    }

    public function renderLabel($label, $options = array())
    {
        $attributes = $options;
        $attributes['class'] = 'control-label';
        return HtmlUtil::renderTag('label', $attributes, $label . '：');
    }

    public function renderHelp($help, $options = array())
    {
        $attributes = $options;
        $attributes['class'] = 'help-block';
        return HtmlUtil::renderTag('span', $attributes, $help);
    }

    public function renderError($error, $options = array())
    {
        $attributes = $options;
        $attributes['class'] = 'help-block error';
        return HtmlUtil::renderTag('span', $attributes, $error);
    }

    public function renderButton($text, $icon, $class, $options = array())
    {
        $icon_html = $icon ? HtmlUtil::renderTag('i', array('class' => $icon)) : null;

        $attributes = $options;
        $attributes['type'] = 'button';
        $attributes['class'] = $class;
        return HtmlUtil::renderTag('button', $attributes, $icon_html . '&nbsp;&nbsp;' . $text . '&nbsp;&nbsp;');
    }

    public function renderSubmitAndCancel($submit_url, $cancel_url)
    {
        $submit_html = $this->renderButton('确定', null, 'btn btn-primary btn-submit ajax-post required-validate', array('url' => $submit_url));
        $cancel_html = $this->renderButton('取消', null, 'btn btn-default btn-cancel redirect', array('url' => $cancel_url));
        return $submit_html . '&nbsp;' . $cancel_html;
    }
}